package com.apestech.api.condition;

import com.apestech.api.condition.Step.*;
import com.apestech.framework.json.JSON;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.util.DateUtil;
import com.apestech.framework.xml.condition.modul.ConditionStrategy;

import java.util.ArrayList;
import java.util.Date;

public class ConditionStrategySingleStepExec extends StepUtil {
    private ConditionStrategy.Step step;
    private String prefix;
    private JSONObject stepInp;
    private JSONObject stepOut;
    private int i;
    private boolean isbreak=false;
    private JSONObject stepMsg;
    private JSONArray stepInfoList;
    private ConditionStrategyExec conditionStrategyExec;

    public ConditionStrategySingleStepExec(ConditionStrategy.Step step, int i, ConditionStrategyExec conditionStrategyExec){
        this.conditionStrategyExec=conditionStrategyExec;
        this.step=step;
        this.i=i;
        stepMsg=new JSONObject();
    }

    public JSONObject getStepMsg() {
        return stepMsg;
    }

    public JSONObject getStepInp() {
        return stepInp;
    }

    public void setStepInp(JSONObject stepInp) {
        this.stepInp = stepInp;
    }

    public JSONObject getStepOut() {
        return stepOut;
    }

    public boolean isIsbreak() {
        return isbreak;
    }

    public JSONArray getStepInfoList() {
        return stepInfoList;
    }

    public void setStepInfoList(JSONArray stepInfoList) {
        this.stepInfoList = stepInfoList;
    }

    public JSONObject execSingleStep() throws Exception {
        isbreak=false;
        if(step.isbPrint()){
            printMsg("执行入参："+ JSON.toJSONString(stepInp), true);
        }
        printMsg(DateUtil.dateTimeToStr(new Date())+"第"+(i+1)+"步："+step.getId()+"-"+step.getName());
        switch (step.getType()) {
            case "if":{
                String exp=step.getFif().getExp();
                Object r=doExpression(exp, stepInp);
                stepMsg.put("STEP_ID",step.getId());
                stepMsg.put("STEP_NAME",step.getId());
                stepMsg.put("STEP_TYPE", step.getType());
                stepMsg.put("DIMENSION_ID",null);
                stepMsg.put("VALUE",JSON.toJSONString(r));
                if(exp!=null){
                    exp=exp.replaceAll("\r\n","&lt;br/&gt;");
                }
                stepMsg.put("EXPRESS",exp);
                stepMsg.put("C_ID",null);
                stepMsg.put("ERROR",step.getNoFoundMsg());
                conditionStrategyExec.addStepInfo(stepMsg);

                if(castToBoolean(r)){
                    ConditionStrategyStepExec stepexec=new ConditionStrategyStepExec(
                            step.getFif().getFthen().getThen(), stepInp, step, conditionStrategyExec);
                    stepexec.execStep();
                    if(step.getFif().getFthen().isbBreak()){
                        isbreak=true;
                        //setBreakData(step.getFif().getFthen().getMsg());
                        throw new Exception(step.getFif().getFthen().getMsg());
                    }
                } else {
                    if(step.getFif().isbElse()) {
                        ConditionStrategyStepExec stepexec = new ConditionStrategyStepExec(
                                step.getFif().getEthen().getThen(), stepInp, step, conditionStrategyExec);
                        stepexec.execStep();
                        if (step.getFif().getEthen().isbBreak()) {
                            isbreak = true;
                            //setBreakData(step.getFif().getEthen().getMsg());
                            throw new Exception(step.getFif().getEthen().getMsg());
                        }
                    }
                }
                break;
            }
            case "while":{
                ConditionStrategy.Step wstep=step.getFwhile().getSql();
                StepWhile fwhile= (StepWhile) wstep.getStepLife();
                fwhile.setInput(stepInp);
                String resultKey=step.getFwhile().getResultKey();
                JSONArray list=new JSONArray();
                String type=wstep.getType();  //sql、queryid、xls、array、json
//                if("json".equals(type) || "array".equals(type)) {
//                    fwhile.setResult(step.getFwhile().getReslut());
//                    fwhile.setOut(resultMap1);
//                }
//                step.getFwhile().setReslut(resultMap1);
                ConditionStrategy.Step finalStep=step;
                fwhile.setArrayCallback(new ArrayCallback() {
                    @Override
                    public JSONObject getRow(JSONObject row) throws Exception {
                        //finalStep.setResultMap(j);
                        JSONObject json=new JSONObject();
                        json.putAll(stepInp);
                        json.putAll(row);
                        ConditionStrategyStepExec stepexec=new ConditionStrategyStepExec(
                                finalStep.getFwhile().getStep(), json, finalStep, conditionStrategyExec);
                        stepexec.execStep();
                        row.putAll(stepexec.getOutput());
                        return row;
                    }
                });
                fwhile.exec();
                //if("json".equals(type) || "array".equals(type)) {
                if(fwhile.getOut()!=null) {
                    list=fwhile.getList();
                    stepOut=fwhile.getOut();
                }
                if(resultKey!=null){
                    stepOut.put(resultKey, list);
                }
                step.setResultMap(stepOut);
            }
            default: {  //conditionStrategy queryid sql  =>default
                if(step.getStepLife()!=null){
                    if(step.getOther()!=null && step.getOther().size()>0){
                        if(step.getOther().get("SYS_NO_CHECK1")!=null){
                            step.getOther().put("SYS_NO_CHECK", step.getOther().get("SYS_NO_CHECK1"));
                            step.getOther().remove("SYS_NO_CHECK1");
                        }
                        String SYS_NO_CHECK1=stepInp.getString("SYS_NO_CHECK");
                        String SYS_NO_CHECK2=step.getOther().getString("SYS_NO_CHECK");
                        if(SYS_NO_CHECK1!=null){
                            if(SYS_NO_CHECK2!=null){
                                if(!SYS_NO_CHECK1.equals(SYS_NO_CHECK2)){
                                    SYS_NO_CHECK1=SYS_NO_CHECK1+","+SYS_NO_CHECK2;
                                }
                            }
                        } else {
                            SYS_NO_CHECK1=SYS_NO_CHECK2;
                        }
                        if(SYS_NO_CHECK1!=null){
//                            inputMap.put("SYS_NO_CHECK",SYS_NO_CHECK1);
//                            resultMap.remove("SYS_NO_CHECK");
//                            resultMap1.remove("SYS_NO_CHECK");
                            step.getOther().put("SYS_NO_CHECK1", step.getOther().get("SYS_NO_CHECK"));
                            step.getOther().remove("SYS_NO_CHECK");
                            step.getOther().put("SYS_NO_CHECK", SYS_NO_CHECK1);
                        }
                    }
                    String mInput=step.getStepLife().showMinInput();
                    if(mInput!=null){
                        printMsg("步骤最小输入项:"+step.getStepLife().showMinInput());
                    }
                    JSONObject j1=new JSONObject();
                    j1.putAll(stepInp);
                    if(step.getPstep()!=null){
                        j1.putAll(step.getPstep().getSuperInput());
                    }
                    j1.putAll(step.getSuperInput());
                    if(step.getOther()!=null){
                        j1.putAll(step.getOther());
                    }
                    step.getStepLife().setInput(j1);
//                    if("conditionStrategy".equals(step.getId())){
//                        ConditionStrategyExec conStrategy= (ConditionStrategyExec) step.getStepLife();
//                        conStrategy.setStepInfo(stepInfoList);
//                    }
                    //step.getStepLife().setInput(getAllInput(step.getSuperInput(), resultMap1, null));
//                        if(pstep!=null){
//                            step.getStepLife().setInput(getAllInput(inputMap, resultMap1, resultMap));
//                        } else {
//                            step.getStepLife().setInput(getAllInput(inputMap, resultMap, resultMap1));
//                        }
                    step.getStepLife().exec();
                    step.getStepLife().setOutput();
                    if(step.isIsremove()){
                        stepInp.remove(step.getId());
                    }
                    step.setResultMap(step.getStepLife().getResultMap());
                    if(stepInfoList==null){
                        stepInfoList=new JSONArray();
                    }

                    printMsg(JSON.toJSONString(step.getResultMap()));
//                    resultMap1.putAll(step.getSuperInput());
//                    resultMap1.putAll(step.getResultMap());
                }
                break;
            }
        }
        if(step.getStepLife()!=null){
            boolean isbreak=step.isIsbreak();
            boolean sysbreak=(step.getResultMap()==null||step.getResultMap().size()==0);
            if(!sysbreak){
                sysbreak="1".equals(step.getResultMap().getString("sys_break"));
            }
            if(isbreak && sysbreak){
                throw new Exception(step.getName()+"["+step.getId()+"]"+"无符合条件的返回数据！");
            }
//            step.getStepLife().setConditionStrategyVar(conditionStrategy, resultMap);
//            step.getStepLife().setOutput();
//            resultMap.putAll(step.getStepLife().getResultMap());
            //条件策略名称、条件类型名称、维度名称、查询返回值、公式、返回值、调整单号、报错信息
            stepMsg.put("STEP_ID",step.getId());
//            stepMsg.put("STEP_NAME",step.getId());
            stepMsg.put("STEP_TYPE", step.getType());
//            stepMsg.put("CONDITION_ID",step.getId());  //.getResultMap().getString("CONDITION_ID")
            stepMsg.put("STEP_NAME",step.getName());  //.getResultMap().getString("CONDITION_NAME")
            String exp=step.getExpress();
            if(exp!=null){
                exp=exp.replaceAll("\r\n","&lt;br/&gt;");
            }
            stepMsg.put("EXPRESS",exp);
            stepMsg.put("ERROR",step.getNoFoundMsg());
            if(step.getResultMap()!=null){
                stepMsg.put("DIMENSION_ID",step.getResultMap().getString("DIMENSION_ID"));
                stepMsg.put("C_ID",JSON.toJSONString(step.getResultMap().getString("C_ID")));
            }
            JSONObject r=null;
            if("condition".equals(step.getType())){
                r= JSON.toJSON(step.getResultMap().get("RESULT_DATA"));
                if(r==null){
                    r=step.getResultMap();
                }
            } else {
                r=step.getResultMap();
            }
            if(r!=null){
                ArrayList<String> klist=r.getKeylist();
                int ilen=klist.size();
                for(int j=0; j<ilen; j++){
                    String k=klist.get(j);
                    if(!"DIMENSION_ID".equals(k) && !"C_ID".equals(k)){
                        JSONObject json=new JSONObject();
                        json.putAll(stepMsg);
                        json.put("KEY", k);
                        json.put("VALUE", r.getString(k));
                        conditionStrategyExec.addStepInfo(json);
                    }
                }
            } else {
                stepMsg.put("VALUE",r);
                conditionStrategyExec.addStepInfo(stepMsg);
            }
        }
        return null;
    }

    private void setBreakData(String msg ){
        if(stepOut==null) {
            stepOut=new JSONObject();
        }
        stepOut.put("sys_break", "1");
        if(msg!=null){
            stepOut.put("sys_msg",msg);
        }
    }

}
